/**
 * 工具类 - 提供常用的功能函数
 */

/**
 * 防抖函数
 * 将多次执行的函数合并成一次执行，在指定时间内多次触发只会执行最后一次
 * @param fn 需要防抖的函数
 * @param delay 延迟时间（毫秒）
 * @returns 防抖处理后的函数
 */
export function debounce<T extends (...args: any[]) => any>(fn: T, delay: number): (...args: Parameters<T>) => void {
  let timer: number | null = null
  
  return function(this: any, ...args: Parameters<T>) {
    if (timer) {
      window.clearTimeout(timer)
    }
    
    timer = window.setTimeout(() => {
      fn.apply(this, args)
      timer = null
    }, delay)
  }
}

/**
 * 节流函数
 * 限制函数在一定时间内只能执行一次，无论触发多少次
 * @param fn 需要节流的函数
 * @param interval 间隔时间（毫秒）
 * @returns 节流处理后的函数
 */
export function throttle<T extends (...args: any[]) => any>(fn: T, interval: number): (...args: Parameters<T>) => void {
  let lastTime = 0
  let timer: number | null = null
  
  return function(this: any, ...args: Parameters<T>) {
    const now = Date.now()
    const remaining = interval - (now - lastTime)
    
    if (remaining <= 0) {
      // 已经超过间隔时间，可以立即执行
      if (timer) {
        window.clearTimeout(timer)
        timer = null
      }
      
      fn.apply(this, args)
      lastTime = now
    } else if (!timer) {
      // 未到间隔时间，设置定时器在剩余时间后执行
      timer = window.setTimeout(() => {
        fn.apply(this, args)
        lastTime = Date.now()
        timer = null
      }, remaining)
    }
  }
}

/**
 * RAF节流函数
 * 使用requestAnimationFrame实现的节流，适合动画和视觉更新
 * @param fn 需要节流的函数
 * @returns 使用RAF节流处理后的函数
 */
export function rafThrottle<T extends (...args: any[]) => any>(fn: T): (...args: Parameters<T>) => void {
  let rafId: number | null = null
  
  return function(this: any, ...args: Parameters<T>) {
    if (rafId) return
    
    rafId = requestAnimationFrame(() => {
      fn.apply(this, args)
      rafId = null
    })
  }
}